import os
import subprocess
import shutil

def convert_to_ogg(input_path, output_path, quality=None):
    """
    转换音频文件为OGG格式
    :param input_path: 输入文件路径
    :param output_path: 输出文件路径
    :param quality: 音频质量 (1-10, 数值越小压缩率越高)
    :return: 是否成功
    """
    cmd = [
        'ffmpeg',
        '-i', input_path,
        '-c:a', 'libvorbis',
        '-y',
        '-loglevel', 'error'
    ]
    
    if quality is not None:
        cmd.extend(['-q:a', str(quality)])
    
    cmd.append(output_path)
    
    try:
        subprocess.run(cmd, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
        return True
    except subprocess.CalledProcessError as e:
        print(f"处理失败: {input_path} -> {output_path} | 错误: {e}")
        return False

def process_file(filepath):
    """处理单个音频文件"""
    filename = os.path.basename(filepath)
    directory = os.path.dirname(filepath)
    base_name, ext = os.path.splitext(filename)
    ext = ext.lower()
    target_file = os.path.join(directory, base_name + '.ogg')
    temp_file = os.path.join(directory, base_name + '.temp.ogg')
    
    processed = False
    is_original_ogg = (ext == '.ogg')
    
    try:
        # 非OGG文件需要转换
        if not is_original_ogg:
            print(f"转换: {filepath} -> {target_file}")
            if convert_to_ogg(filepath, temp_file, quality=5):
                # 替换原始文件
                shutil.move(temp_file, target_file)
                # 删除原文件
                os.remove(filepath)
                filepath = target_file
            else:
                if os.path.exists(temp_file):
                    os.remove(temp_file)
                return False
        
        # 检查文件大小
        file_size = os.path.getsize(filepath)
        if file_size <= 30 * 1024:  # 30KB
            print(f"文件已符合要求: {filepath} ({file_size/1024:.2f}KB)")
            return True
            
        print(f"压缩: {filepath} ({file_size/1024:.2f}KB > 30KB)")
        
        # 压缩质量参数序列
        qualities = [5, 4, 3, 2, 1] if is_original_ogg else [3, 2, 1]
        
        for quality in qualities:
            if convert_to_ogg(filepath, temp_file, quality=quality):
                temp_size = os.path.getsize(temp_file)
                
                # 检查压缩后大小
                if temp_size <= 30 * 1024:
                    # 保留压缩后文件
                    shutil.move(temp_file, filepath)
                    print(f"压缩成功: {filepath} -> {temp_size/1024:.2f}KB (质量:{quality})")
                    return True
                elif quality != 1:
                    # 压缩后仍太大，继续尝试更高压缩率
                    os.remove(temp_file)
        
        print(f"警告: {filepath} 无法压缩至30KB以下，将保留原大小")
        return False
    
    except Exception as e:
        print(f"处理文件 {filepath} 时出错: {e}")
        if os.path.exists(temp_file):
            os.remove(temp_file)
        return False

def process_directory(start_dir='.'):
    """递归处理目录及其子目录中的音频文件"""
    audio_extensions = ('.mp3', '.wav', '.flac', '.m4a', '.aac', '.ogg')
    processed_files = 0
    
    for root, dirs, files in os.walk(start_dir):
        # 避免处理.git等隐藏目录
        dirs[:] = [d for d in dirs if not d.startswith('.')]
        
        for filename in files:
            ext = os.path.splitext(filename)[1].lower()
            if ext in audio_extensions:
                filepath = os.path.join(root, filename)
                if process_file(filepath):
                    processed_files += 1
    
    return processed_files

if __name__ == "__main__":
    # 检查ffmpeg是否可用
    try:
        subprocess.run(['ffmpeg', '-version'], 
                      check=True, 
                      stdout=subprocess.DEVNULL, 
                      stderr=subprocess.DEVNULL)
        print("发现 ffmpeg, 开始处理音频文件...\n")
        processed_count = process_directory()
        print(f"\n处理完成, 共处理 {processed_count} 个音频文件")
    except FileNotFoundError:
        print("错误: 未找到 ffmpeg, 请先安装")
    except subprocess.CalledProcessError:
        print("错误: ffmpeg 执行失败")